// useMixin.js - 组合式 API

import { reactive, toRefs, getCurrentInstance, onMounted } from "vue";
export function myMixin(props) {
  const data = reactive({
    transition: 0,
    activeMenuIndex: 0, //选中的index
    // activeLeftMenu: "login",
    // 左侧菜单
    topNavList: props.topNavList,
    contentScrollW: 0,
    scrollLeft: 0,
    endSliderLeft: 0,
    sliderLeft: 0,
    sliderWidth: 0,
    swiperWidth: 0,
    itemPading: 0, //顶部每项tab pading
    isClick: false, //是否点击滑动
  });
  onMounted(() => {
    getSliderWidth();
    getScrollinfo();
    getScrollItemInfo();
    getSwiperWidth();
  });

  // 设置滑块初始位置
  const setInitSliderLeft = () => {
    data.sliderLeft =
      (data.topNavList[data.activeMenuIndex].width - data.sliderWidth) / 2;
    data.itemPading = data.topNavList[data.activeMenuIndex].left;
    data.endSliderLeft = data.sliderLeft;
  };
  // 点击顶部导航时
  const activeMenuFn = (code, index) => {
    data.transition = 0.2;
    // 点击时需要设置点击状态，禁止轮播执行滑动事件
    data.isClick = true;
    data.activeMenuIndex = index;
    // 单独设置滑块位置
    let nextEle = data.topNavList[data.activeMenuIndex];
    // 当前滑块距离当前tabs前的left
    const swiperScope = (nextEle.width - data.sliderWidth) / 2;
    // 滑块left目标 = 当前滑块距离当前tabs前的left + 当前tabs的left - itemPading
    data.sliderLeft = swiperScope + nextEle.left - data.itemPading;
    setScrollLeft(index);
  };
  // 点击tabs时,设置顶部tab选中项居中
  const setScrollLeft = (index) => {
    // 设置选中tabs在中间显示
    data.scrollLeft =
      data.topNavList[index].left -
      data.contentScrollW / 2 +
      data.topNavList[index].width / 2;
  };
  // 获取滚动元素位置信息
  const { proxy } = getCurrentInstance();
  // 获取顶部tabs滚动元素信息
  const getScrollinfo = () => {
    const query = uni.createSelectorQuery().in(proxy);
    query
      .select(".top-tabs-scroll")
      .boundingClientRect((ele) => {
        // 拿到 scroll-view 组件宽度
        data.contentScrollW = ele.width;
      })
      .exec();
  };
  // 获取顶部tabs每一项信息
  const getScrollItemInfo = () => {
    const query = uni.createSelectorQuery().in(proxy);
    query
      .selectAll(".menu-item-tabs")
      .boundingClientRect((ele) => {
        let dataLen = ele.length;
        // console.log("ele", ele);
        for (let i = 0; i < dataLen; i++) {
          //  scroll-view 子元素组件距离左边栏的距离
          data.topNavList[i].left = ele[i].left;
          //  scroll-view 子元素组件宽度
          data.topNavList[i].width = ele[i].width;
        }
      })
      .exec(() => {
        setInitSliderLeft();
      });
  };
  // 获取滑块的宽度
  const getSliderWidth = () => {
    const query = uni.createSelectorQuery().in(proxy);
    query
      .select(".slider-style")
      .boundingClientRect((ele) => {
        data.sliderWidth = ele.width;
      })
      .exec();
  };
  // 获取底部轮播每项的宽度
  const getSwiperWidth = () => {
    const query = uni.createSelectorQuery().in(proxy);
    query
      .select(".swiper")
      .boundingClientRect((ele) => {
        data.swiperWidth = ele.width;
      })
      .exec();
  };

  // 手动滑动时底部内容区域切换时
  const transitionFn = (e) => {
    // 如果时点击顶部tabs触发禁止执行一下代码
    if (data.isClick) return;
    data.transition = 0;
    // 以下时用户手动滑动时触发的逻辑
    // 根据用户左右滑动速度设置滑块的移动距离和速度
    const currentDx = e.detail.dx; //横向滚动距离,正值向右，负值向左
    // 滑动完成率
    const wProportion = Math.abs(currentDx / data.swiperWidth);
    // 完成率大于1时 return;
    if (wProportion > 1) return;
    // 下面时判断滑动方向,设置下一个滑向的元素
    let nextEle = null;
    if (currentDx < 0) {
      nextEle = data.topNavList[data.activeMenuIndex - 1];
    } else {
      nextEle = data.topNavList[data.activeMenuIndex + 1];
    }
    // 滑动到最前或最后时 return;
    if (!nextEle) return;
    // 当前滑块距离当前tabs前的left
    const swiperScope = (nextEle.width - data.sliderWidth) / 2;
    // 滑块全部的移动距离,下一个tab宽度加上left，减去padding,就是全部移动的left
    const allMoveLeft = swiperScope + nextEle.left - data.itemPading;
    // 计算真正需要移动的left,全部left减去上一次的left
    const moveLeft = allMoveLeft - data.endSliderLeft;
    // 需要自动的left*完成率在加上之前的left
    data.sliderLeft = moveLeft * wProportion + data.endSliderLeft;
  };
  // 滑动完成时
  const animationfinishFn = (e) => {
    data.isClick = false;
    data.activeMenuIndex = e.detail.current;
    data.endSliderLeft = data.sliderLeft;
    // 将选中tab居中展示
    setScrollLeft(data.activeMenuIndex);
  };
  return {
    activeMenuFn,
    transitionFn,
    animationfinishFn,
    ...toRefs(data),
  };
}
